#include<cstdio>
#include<iostream>
#include<fstream>
#include<vector>

using namespace std;

vector<int> genGammaCode(int n) {
   vector<int> *code = new vector<int>();
   int len = 0;
   for(n; n > 0; n/=2) {
      code->push_back(n%2);
      len++;
   }
   for(int i=0; i < len-1; i++) {
      code->push_back(0);
   }
   return *code;
}

int decode(vector<int> code) {
   int n = 1;
   int res = 0;
   int len = code.size();
   for(int i = len - 1; i >= 0; i--){
      res += code[i]*n;
      n *= 2;
   }
   return res;
}

vector<int> readBinFile(const char *filename) {
   ifstream fin(filename, ios_base::binary);
   vector<int> *ret = new vector<int>();
   int pos = -1;
   int n = 0;
   char byte = 0;
   bool len = true;
   vector<int> *code = new vector<int>();
   while(fin.get(byte)){
      for(pos = 7; pos >= 0; pos--) {
         if((((byte>>pos)&1) == 0) && len){
            n++;
            continue;
         }
         else
            len = false;
         cout << ((byte>>pos)&1);
         code->push_back((byte>>pos)&1);
         n--;
         if(n == -1) {
            len = true;
            ret->push_back(decode(*code));
            code->clear();
            n=0;
         }
      }
   }
   cout << endl;
   fin.close();
   return *ret;
}

void writeBinFile(const char *filename, vector<int> input) {
   ofstream fout(filename, ios_base::binary);
   
   vector<int> *c = new vector<int>();
   vector<int> d;
   vector<int>::iterator iter;

   for( iter = input.begin(); iter != input.end(); iter++ ) {
      d = genGammaCode(*iter);
      c->insert(c->begin(), d.begin(), d.end());
   }

   int pos = 7;
   char byte = 0;
   for(int i = c->size() - 1; i >= 0; i--){
      if(pos == -1){
         fout << byte;
         
         pos = 7;
         byte = 0;
      }
      byte |= (c->at(i)<< pos);
      pos--;
   }
   fout << byte;
   fout.close();
}

int main() {
   vector<int> *testowy = new vector<int>();
   testowy->push_back(4);
   testowy->push_back(150);
   testowy->push_back(32);
   testowy->push_back(1249);
   testowy->push_back(4325);
   writeBinFile("bin.bin", *testowy);
   *testowy = readBinFile("bin.bin");
   for(int i = 0; i < testowy->size(); i++)
      cout << testowy->at(i) << endl;
   /*
   ifstream fin("probny.bin", ios_base::binary);   
   int pos = -1;
   int n = 0;
   char byte = 0;
   bool len = true;
   vector<int> *code = new vector<int>();
   while(fin.get(byte)){
      for(pos = 7; pos >= 0; pos--) {
         if((((byte>>pos)&1) == 0) && len){
            n++;
            continue;
         }
         else
            len = false;
         cout << ((byte>>pos)&1);
         code->push_back((byte>>pos)&1);
         n--;
         if(n == -1) {
            len = true;
            cout << endl << decode(*code) << endl;
            code->clear();
            n=0;
         }
      }
   }
   cout << endl;
   fin.close();*/
   return 0;
}
